package service;

import annotation.DependencyInjection;
import annotation.Singleton;
import entity.User;
import enums.ResponseErrorCode;
import exception.ServerException;
import repository.UserRepository;
import response.user.*;

import java.util.List;

@Singleton
public class UserService {
    private UserRepository userRepository;

    @DependencyInjection
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public UserRegisterResponse register(String username, String password, String nickname, String avatar) {
        userRepository.startWrite();
        try {
            User user = userRepository.getByUsername(username);
            if (user != null) {
                throw new ServerException(ResponseErrorCode.USERNAME_ALREADY_USED);
            }

            userRepository.add(new User(username, password, nickname, avatar));
            return new UserRegisterResponse(true);
        } finally {
            userRepository.endWrite();
        }
    }

    public UserLoginResponse login(String username, String password) {
        userRepository.startRead();
        try {
            User user = userRepository.getByUsername(username);

            if (user == null || !user.getPassword().equals(password)) {
                throw new ServerException(ResponseErrorCode.LOGIN_ERROR);
            }

            return new UserLoginResponse(true);
        } finally {
            userRepository.endRead();
        }
    }

    public NicknameChangeResponse changeNickname(String username, String nickname) {
        userRepository.startWrite();
        try {
            boolean success = userRepository.changeNickname(username, nickname);
            return new NicknameChangeResponse(success);
        } finally {
            userRepository.endWrite();
        }
    }

    public PasswordChangeResponse changePassword(String username, String oldPassword, String newPassword) {
        userRepository.startWrite();
        try {
            User user = userRepository.getByUsername(username);
            if (user == null) {
                return new PasswordChangeResponse(false);
            }
            if (!user.getPassword().equals(oldPassword)) {
                return new PasswordChangeResponse(false);
            }

            boolean success = userRepository.changePassword(username, newPassword);
            return new PasswordChangeResponse(success);
        } finally {
            userRepository.endWrite();
        }
    }

    public UserListResponse getAllUsers() {
        userRepository.startRead();
        try {
            List<User> userList = userRepository.getAllUsers();
            return new UserListResponse(userList);
        } finally {
            userRepository.endRead();
        }
    }

    public UserGetResponse getUser(String username) {
        userRepository.startRead();
        try {
            User user = userRepository.getByUsername(username);
            if (user == null) {
                throw new ServerException(ResponseErrorCode.USER_NOT_EXISTED);
            }
            return new UserGetResponse(user);
        } finally {
            userRepository.endRead();
        }
    }
}
